#pragma once 

#include "basetypes.h"
#include <iostream>

typedef char Byte;

namespace GiovaMath
{
	class BigNumber
	{

	public:

		//explicit BigNumber(UInt32 pageSize = 1);					// it's a bad idea!!!
		explicit BigNumber(UInt64 number = 0, UInt32 pageSize = 1);
		explicit BigNumber(const char* sNumber, UInt32 pageSize = 1);
		BigNumber(const BigNumber &bNumber);
		~BigNumber();

		BigNumber&	operator= (const BigNumber& bNumber);
		BigNumber&	operator-= (const BigNumber& bNumber);	// TODO
		BigNumber&	operator+= (const BigNumber& bNumber);
		BigNumber&	operator*= (const BigNumber& bNumber);
		BigNumber&	operator/= (const BigNumber& bNumber);	// TODO

		BigNumber&	operator= (UInt32 number);
		BigNumber&	operator-= (UInt32 number);	// TODO
		BigNumber&	operator+= (UInt32 number);
		BigNumber&	operator*= (UInt32 number);
		BigNumber&	operator/= (UInt32 number);	// TODO

		BigNumber&	operator++ ();
		BigNumber	operator++ (int);
		BigNumber&	operator-- ();
		BigNumber	operator-- (int);

		BigNumber	operator- (const BigNumber& bNumber) const;	// TODO
		BigNumber	operator+ (const BigNumber& bNumber) const;
		BigNumber	operator* (const BigNumber& bNumber) const;
		BigNumber	operator/ (const BigNumber& bNumber) const;	// TODO

		bool		operator==(const BigNumber& bNumber) const;
		bool		operator!=(const BigNumber& bNumber) const;

		bool		operator>(const BigNumber& bNumber) const;
		bool		operator<(const BigNumber& bNumber) const;

		inline UInt64 toInt64(UInt32 fromDigit = 0) const;
		inline UInt32 getDigitNum() const { return mIndex + 1; }
		inline Byte getDigitAt(UInt32 i) const { return mData[i]; } 
		inline void	clearToZero()
		{
			mIndex = 0;
			memset(mData, 0, mLenght);
		}

	private:

		inline void _allocMemory(UInt32 amount = 0);

		friend std::ostream& operator<<(std::ostream& out, const BigNumber& bNumber)
		{
			for (Int64 i = bNumber.mIndex ; i >= 0; --i)
			{
				out << static_cast<unsigned short>(bNumber.mData[i]);
			}

			return out;
		}

	private:

		Byte*	mData;
		UInt32	mPageSize;
		UInt32	mIndex;
		UInt32	mLenght;


	};
}
